package com.amani.module.medical_supplies.util;

import com.amani.module.medical_supplies.config.SFDConstant;
import com.github.wxiaoqi.security.common.util.JacksonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class OrderNumUtil {

    public enum OrderType{
        /**
         * 按需求自行添加, 需要在@see application-sfd.properties里添配置
         */
        // 首营商品审批
        FirstGoods("FirstGoods"),
        // 首营企业审批
        FirstCompany("FirstCompany"),
        // 销售订单
        SaleOrder("saleOrder"),
        // 手动移库单
        ManualTransfer("manualTransfer"),
        // 库存商品调整单
        InvGoodsAdjust("InvGoodsAdjust"),
        // 唯一码维护
        UniqueCodeM("UniqueCodeM"),
        // 商品期初单
        GoodsInitial("GoodsInitial"),
        // 其他收款核销录入单
        OtherReceivablesV("OtherReceivablesV"),
        // 其他收款录入单
        OtherReceivables("OtherReceivables"),
        // 其他付款录入单
        OtherPayment("OtherPayment"),
        // 供应商期初单
        SupplierInitial("SupplierInitial"),
        // 唯一码期初导入单
        CodeInitial("CodeInitial"),
        // 库存盘点单
        StockCheck("StockCheck"),
        // 销售退货订单
        SaleOrderReturn("saleOrderReturn"),
        // 销售退货订单
        SaleOrderReturnSheetNo("SheetNosaleOrderReturn"),
        // 销售换票
        SaleChange("saleChange"),
        // 销售结算
        SaleSettlement("saleSettlement"),
        // 销售确认
        SaleConfirm("saleConfirm"),
        // 入库验收通知单号
        InStorage("inStorage"),
        // 植入介入单号
        ImplantedProductFeedback("implantedProductFeedback"),
        // 采购订单
        PurchaseOrder("purchaseOrder"),
        // 采购记账
        PurchaseBill("purchaseBill"),
        //采购收货单
        StorageReceivingNote("StorageReceivingNote"),
        // 采购预付付款申请单
        PurchasePrepayOrderApply("purchasePrepayOrderApply"),
        // 入库冲补差价
        InboundReplenishment("InboundReplenishment"),
        // 在途商品组票
        InTransitGoodsGroupTicket("InTransitGoodsGroupTicket"),
        // 发票录入
        InvoiceEntry("InvoiceEntry"),
        // 报损单
        DamagedForm("DamagedForm"),
        // 供应商直接预付申请单
        SupplierPrepayOrder("SupplierPrepayOrder"),
        // 采购流水
        AccountsSheet("AccountsSheet"),
        //物流中心调拨
        Allocation("Allocation"),
        //入库上架单
        InStoragePutOnShelves("InStoragePutOnShelves"),
        //出库复核
        OutStockApproval("OutStockApproval"),
        //采退申请
        PurchaserReturnApply("PurchaserReturnApply"),
        //组装备货单
        BomStockingUp("BomStockingUp"),
        //商品报溢
        GoodsReportSpillOver("GoodsReportSpillOver"),
        //组装品物流中心调拨单
        BomLogist("BomLogist"),
        //组装品物流中心出库复核
        BomLogistOutStock("BomLogistOutStock"),
        //组装品物流中心入库验收
        BomLogistInStock("BomLogistInStock"),
        //组装品子件抽取单
        AssemblyVarietyOfSonSheet("AssemblyVarietyOfSonSheet"),
        //组装拆卸单
        AssembleVarietyDismantlingList("AssembleVarietyDismantlingList");




        /**
         * @param preKey 对应配置文件的key
         */
        OrderType(String preKey){
            this.preKey = preKey;
        }
        private String preKey;          // 配置文件里订单前缀key
        public String getPreKey() { return preKey; }
        public void setPreKey(String preKey) { this.preKey = preKey; }
    }

    private static final String KEY_REDIS_PRE = "xxx_cache_order_";
    private static final String KEY_DATE = "date";
    private static final String KEY_NUMBER = "num";
    private static RedisTemplate<String, String> mRedis;
    private static SimpleDateFormat mFormat = new SimpleDateFormat("yyyyMMdd");

    @Autowired
    private RedisTemplate<String, String> redis;

    @PostConstruct
    public void init() {
        OrderNumUtil.mRedis = redis;
    }

    /**
     * 创建一个订单号
     * @return
     */
    public static String CreateOrderNum(OrderType type){
        String sn=createSerialNo(type);
        /*while (sheetStatusService.exist(sn)){
            sn=createSerialNo(type);
        }*/
        return sn;
    }
    private synchronized static String createSerialNo(OrderType type){
        String lastTime;
        Integer index;
        String json = mRedis.boundValueOps(KEY_REDIS_PRE+type.preKey).get();
        if(json == null || "".equals(json)){
            lastTime = mFormat.format(new Date());
            index = 0;
        }else{
            Map map = null;
            try {
                map = JacksonUtil.toMap(json);
            } catch (Exception e) {
                e.printStackTrace();
            }
            lastTime = (String) map.get(KEY_DATE);
            index = (Integer) map.get(KEY_NUMBER);
        }

        String t = mFormat.format(new Date());
        if(!t.equals(lastTime)){
            lastTime = t;
            index = 0;
        }
        index++;
        Map<String, Object> map = new HashMap<>();
        map.put(KEY_DATE, t);
        map.put(KEY_NUMBER, index);
        try {
            mRedis.boundValueOps(KEY_REDIS_PRE+type.preKey).set(JacksonUtil.toJSon(map));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return String.format("%s%s%06d", SFDConstant.ORDER_PRE.get(type.preKey), lastTime, index);
    }
}
